<script lang="ts" setup>
import { getTree, useLoginUserStore, urls, insertOne, updateOne } from '@/index';
import type { Department, TreeNodeDataType } from '@/index.d';
import type { ElTree } from 'element-plus';
import type Node from 'element-plus/es/components/cascader-panel/src/node';
import { useRequest } from 'vue-request';

const loginUserStore = useLoginUserStore();
const { loginUser } = loginUserStore;

const currentDepartmentId = defineModel('currentDepartmentId', { type: Number });

const currentDepartmentLabel = defineModel('currentDepartmentLabel', {
  type: String
});

const defaultExpandedKeys = computed(() => {
  const arr = new Array();
  arr.push(currentDepartmentId.value);
  return arr;
});

const departmentItemUpdateVisible = ref<boolean>(false);

const {
  data: departmentListWithoutPage,
  run: getDepartmentListWithoutPage,
  loading
} = useRequest(() => getTree<Department>(urls.department));

const departmentTreeData = computed<Department[]>(
  () => departmentListWithoutPage.value as Department[]
);

const handleInsert = async (_node: any, data: TreeNodeDataType) => {
  console.log('handleInsert');
  //1、构造一个新的节点
  const newChild: TreeNodeDataType = {
    pid: data.id as number,
    label: '新的节点',
    isRoot: false,
    children: []
  };
  //2、将新的节点插入到数据库中
  const res = (await insertOne(urls.department, newChild)) as TreeNodeDataType;
  //3、插入成功后，更新成功后，重新加载树。
  res && getDepartmentListWithoutPage();
};

const showUpdate = async (node: Node) => {
  currentDepartmentId.value = node.data?.id as number;
  currentDepartmentLabel.value = node.data?.label as string;
  departmentItemUpdateVisible.value = true;
};

const handleUpdate = async (node: Node) => {
  //1、更新数据到数据库
  const res = await updateOne(urls.department, {
    id: node.data?.id as number,
    label: currentDepartmentLabel.value
  });
  //2、更新成功后，重新加载树。
  res && getDepartmentListWithoutPage();
};

const departmentTreeRef = ref<InstanceType<typeof ElTree>>();

const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return data.label.includes(value);
};

const searchKeyword = ref<string>();

watch(searchKeyword, val => {
  departmentTreeRef.value!.filter(val);
});

const handleCurrentChange = (data: Department, node: Node) => {
  currentDepartmentId.value = data.id;
  currentDepartmentLabel.value = data.label;
};

const allowDrag = (node: any) => {
  return !node.data.isRoot;
};

const allowDrop = (_draggingNode: any, dropNode: any, type: 'prev' | 'inner' | 'next') => {
  switch (type) {
    case 'prev':
      return false;
    case 'inner':
      return true;
    case 'next':
      return !dropNode.data.isRoot;
  }
};

const handleNodeDrop = async (
  node: any,
  toNode: any,
  type: 'before' | 'after' | 'inner',
  _event: Event
) => {
  if (type === 'inner') {
    const res = (await updateOne(urls.department, {
      id: node.data.id,
      pid: toNode.data.id
    })) as TreeNodeDataType;

    if (res !== undefined) {
      getDepartmentListWithoutPage();
    }
  }

  if (type === 'after') {
    if (node.data.parent === toNode.data.parent) {
      return;
    } else {
      const res = (await updateOne(urls.department, {
        id: node.data.id,
        pid: toNode.data.id
      })) as TreeNodeDataType;

      if (res !== undefined) {
        getDepartmentListWithoutPage();
      }
    }
  }
};
</script>
<template>
  <el-input v-model="searchKeyword" placeholder="请输入部门关键字" class="searh-input" clearable />
  <el-scrollbar>
    <el-tree
      ref="departmentTreeRef"
      :data="departmentTreeData"
      :loading="loading"
      node-key="id"
      draggable
      auto-expand-parent
      highlight-current
      :expand-on-click-node="false"
      :current-node-key="currentDepartmentId"
      :filter-node-method="filterNode"
      :default-expanded-keys="defaultExpandedKeys"
      @current-change="handleCurrentChange"
      :allow-drag="allowDrag"
      :allow-drop="allowDrop"
      @node-drop="handleNodeDrop"
    >
      <template #default="{ node, data }">
        <div class="department-item-wrapper">
          <div class="department-item-label">
            {{ data.label }}
          </div>
          <div class="department-item-operator">
            <div
              class="department-item-operator-update"
              v-if="departmentItemUpdateVisible && currentDepartmentId === data.id"
            >
              <div class="tree-operator-update-input">
                <el-input size="small" v-model="currentDepartmentLabel" clearable></el-input>
              </div>
              <el-button-group class="tree-operator-update-button">
                <el-button link type="primary" size="small" @click="handleUpdate(node)">
                  确认
                </el-button>
                <el-button
                  link
                  type="warning"
                  size="small"
                  @click="departmentItemUpdateVisible = false"
                >
                  关闭
                </el-button>
              </el-button-group>
            </div>
            <el-button-group>
              <span>
                <el-button link type="primary" size="small" @click="handleInsert(node, data)">
                  增加
                </el-button>
              </span>
              <span>
                <el-button
                  v-if="data.id !== 0"
                  link
                  type="warning"
                  size="small"
                  @click="showUpdate(node)"
                >
                  修改
                </el-button>
              </span>
              <span> <HqPopconfirm v-if="data.id !== 0" /></span>
            </el-button-group>
          </div>
        </div>
      </template>
    </el-tree>
  </el-scrollbar>
</template>
<style lang="scss" scoped>
.searh-input {
  margin-bottom: 5px;
}

.department-item-wrapper {
  display: flex;
  width: 100%;
  justify-content: space-between;

  .department-item-label {
    height: 24px;
    line-height: 24px;
  }

  .department-item-operator {
    display: flex;
    .department-item-operator-update {
      width: 400px;
      display: flex;
      margin-right: 5px;
      .tree-operator-update-input {
        flex: 1;
      }
    }
  }

  .el-button-group {
    padding: 3px 0;
    display: inline-flex;

    > span {
      width: 30px;
      height: 19px;
    }
  }
}
</style>
